home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 August: Tool Chest / Dev.CD Aug 94.toast / Sample Code / Newton Sample Code 1.1 / Communications / Slurp-3 / Slurp.text < prev    next >
Encoding:
Text File  |  1994-03-08  |  20.1 KB  |  688 lines  |  [TEXT/MPS ]

  1. // © Copyright 1993-94 Apple Computer, Inc, All Rights Reserved
  2.  
  3. constant kAppSymbol := '|Slurp:PIEDTS|;
  4. constant kPackageName := '|Slurp:PIEDTS|;
  5. constant kAppObject := '["soup","soups"];
  6.  
  7. constant kSoupName := kPackageName;
  8. constant kSoupIndexes := '[/* {structure: slot, path: name.first, type: string} */];
  9.  
  10.  
  11. func zGetSound(name, file)
  12. begin;
  13.    local rf := OpenResFileX(file);
  14.    local snd := {sndFrameType: 'simpleSound,
  15.      samples: GetSndAsSamples(name),
  16.      samplingRate: 22026.43172,
  17.      dataType: 1,
  18.      compressionType: 0};
  19.    CloseResFileX(rf);
  20.    return snd;
  21. end;
  22.  
  23. func zGetSound11(name, file)
  24. begin;
  25.    local rf := OpenResFileX(file);
  26.    local snd := {sndFrameType: 'simpleSound,
  27.      samples: GetSndAsSamplesRate11KHz(name),
  28.      samplingRate: 11013.21586,
  29.      dataType: 1,
  30.      compressionType: 0};
  31.    CloseResFileX(rf);
  32.    return snd;
  33. end;
  34.  
  35. homeDir := "Beeld:Desktop Folder:New Slurp:";
  36.  
  37. theSlurpSound := zGetSound11("Slurping", "Slurping");
  38.  
  39. // ---- End Project Data ----
  40.  
  41.  
  42. // ---- File SlurpBaseView.t ----
  43. slurpBaseView :=
  44.    {newEntry: nil,
  45.     viewSetupDoneScript:
  46.       func()
  47.       begin
  48.          :newStatus("Click Receive..., the send file from Mac...");
  49.       
  50.          self.commEndPt := { _proto:   protoSerialProtocol,
  51.                              _parent:  self,
  52.                              slurpBaseView:  self};
  53.       
  54.          PlaySound(slurpSound);
  55.       end,
  56.     epDisconnect:
  57.       func()
  58.       begin
  59.       //   RemoveSlot(commEndPt, 'slurpBaseView);
  60.       
  61.          commEndPt:Abort();
  62.       
  63.          commEndPt:Release();
  64.       end,
  65.     viewQuitScript:
  66.       func()
  67.       begin
  68.       //in your viewQuitScript, call
  69.       //   :UnRegisterCardSoup(kSoupName);
  70.       
  71.          if StrEqual(receiveBtn.text, "Disconnect") then begin
  72.             RemoveSlot(commEndPt, 'slurpBaseView);
  73.             :epDisconnect();
  74.          end;
  75.       
  76.          inherited:?viewQuitScript();
  77.       end,
  78.     RegisterCardSoup:
  79.       func(soupName,soupIndexes,appSymbol,appObject)
  80.         //returns a union-soup for your app to use
  81.         begin
  82.           //first check for system provided function
  83.           if functions.RegisterCardSoup then
  84.             return RegisterCardSoup(soupName,soupIndexes,appSymbol,appObject);
  85.       
  86.           CreateAppSoup(soupName,soupIndexes,EnsureInternal([appSymbol]),EnsureInternal(appObject));
  87.                  
  88.           //ensure your soup will exist on stores which later become available
  89.           AddArraySlot(CardSoups,soupName);
  90.           AddArraySlot(CardSoups,soupIndexes);
  91.           
  92.           //ensure your soup exists on all currently available stores
  93.           local store;
  94.           foreach store in GetStores() do
  95.             if NOT store:IsReadOnly() AND NOT store:HasSoup(soupName) then
  96.               store:CreateSoup(soupName,soupIndexes);
  97.           
  98.           GetUnionSoup(soupName);
  99.         end,
  100.     entrySpec: nil,
  101.     addNewEntry:
  102.       /* addNewEntry
  103.             Add a new entry into the soup.  
  104.       
  105.           Slots used:
  106.          entryIndex,entryString
  107.          newEntry,entrySpec
  108.          testSoup
  109.          testSoupName
  110.          
  111.               
  112.           Methods used:
  113.               n/a
  114.           
  115.           Assumptions:
  116.               none
  117.       */
  118.       func(s)
  119.       begin
  120.          // Setup the input buffer.  Our inputScripts give us
  121.          // a line at a time.
  122.          entryIndex := 0;
  123.          entryString := s;
  124.       
  125.       //   :newStatus("addNewEntry: before currentEntryDisplay");
  126.          currentEntryDisplay:newMsg(s);
  127.       //   :newStatus("addNewEntry: after currentEntryDisplay");
  128.       
  129.          // Now initialize the new entry by cloning the
  130.          // entry specification we got earlier.  This is
  131.          // a frame with the same slots as a soup entry,
  132.          // with sample slot values that are used to
  133.          // specify the desired type for the data.
  134.          newEntry := Clone(entrySpec);
  135.          newEntry := :buildEntry(newEntry);
  136.       //   :newStatus("addNewEntry: after buildEntry");
  137.       
  138.          // Fix the sortOn slot in the entry.
  139.          // The sortOn slot contains a reference to the string in
  140.          // either the names.last slot or the company slot.
  141.          // This allows the Names app to keep a single index
  142.          // on the sortOn slot, while still sorting by
  143.          // either the names.last or company slotc values...
  144.          if newEntry.sortOn = 'name then
  145.             newEntry.sortOn := SetClass(newEntry.name.last, 'name);
  146.          else
  147.             newEntry.sortOn := SetClass(newEntry.company, 'company);
  148.       
  149.          // Now, assuming we have an entry, add it to
  150.          // the default storage device.
  151.          targetSoup:AddToDefaultStore(newEntry);
  152.       //   :newStatus("addNewEntry: after AddToDefaultStore");
  153.       
  154.          // Flush our changes...
  155.          targetSoup:Flush();
  156.       //   :newStatus("addNewEntry: after targetSoup");
  157.       
  158.          // Tell the rest of the world that something has
  159.          // changed.
  160.          BroadcastSoupChange(targetSoupName);
  161.       //   :newStatus("addNewEntry: after BroadcastSoupChange");
  162.       
  163.          numEntries := numEntries + 1;
  164.          SetValue(entriesSlurped, 'text, "" & numEntries);
  165.       
  166.       //   :newStatus("addNewEntry: after addNewEntry");
  167.       end,
  168.     targetSoup: nil,
  169.     newSoupName:
  170.       func(s)
  171.       begin
  172.         :newStatus("Setting new soup name...");
  173.          self.targetSoupName := SubStr(s, 0, StrPos(s, "\n", 0));
  174.          self.targetSoup := GetUnionSoup(targetSoupName);
  175.          SetValue(soupNameDisplay, 'text, targetSoupName);
  176.          :newStatus("Waiting for entrySpec...");
  177.       end,
  178.     viewBounds: {left: -2, top: 2, right: 227, bottom: 239},
  179.     _proto: protoApp,
  180.     epInit:
  181.       func()
  182.       begin
  183.          local   epErr := nil;
  184.       
  185.          commEndPt := { _proto:   protoSerialProtocol,
  186.                         _parent:  self,
  187.                         slurpBaseView:  self};
  188.       
  189.          :newStatus("Instantiating endpoint...");
  190.          epErr := commEndPt:Instantiate(commEndPt, nil);
  191.        
  192.          Perform(epState, 'showState, ["After Instantiate:"]);
  193.       
  194.          if epErr then
  195.          begin
  196.             :newStatus("Instantiate Error:" && NumberStr(epErr));
  197.             return;
  198.          end;
  199.          else
  200.             :newStatus("Instantiating endpoint...done.");
  201.       
  202.          :newStatus("Ready to connect...");
  203.       
  204.          numEntries := 0;
  205.       end,
  206.     protoSerialProtocol:
  207.       {
  208.          _proto: protoEndpoint,         // the basic endpoint
  209.       
  210.          configOptions: [
  211.             { label: kCMSAsyncSerial, type: 'service, opCode: opSetRequired },
  212.             { label: kCMOSerialIOParms, type: 'option, opCode: opSetNegotiate,
  213.                data: { bps: k9600bps, dataBits: k8DataBits, stopBits: k1StopBits, parity: kNoParity } },
  214.             { label: kCMOInputFlowControlParms, type: 'option, opCode: opSetNegotiate,
  215.                data: { xonChar: unicodeDC1, xoffChar: unicodeDC3, useSoftFlowControl: true, useHardFlowControl: nil } },
  216.             ],   
  217.       
  218.          exceptionHandler: func(exception)
  219.          begin
  220.             Perform(endpoint.slurpBaseView, 'newStatus, ["exceptionHandler called..."]);
  221.          end,
  222.       
  223.          waitForSoupName:
  224.          {
  225.             InputForm: 'string,
  226.             endCharacter: UnicodeCR,
  227.        
  228.             InputScript: func(endpoint, s)
  229.             begin
  230.                Perform(endpoint.slurpBaseView, 'newSoupName, [s]);
  231.                endpoint:SetInputSpec(endpoint.waitForEntrySpec);
  232.             end,
  233.             discardAfter: 1000,
  234.          },
  235.       
  236.          waitForEntrySpec:
  237.          {
  238.             InputForm: 'string,
  239.             endCharacter: UnicodeCR,
  240.        
  241.             InputScript: func(endpoint, s)
  242.             begin
  243.                Perform(endpoint.slurpBaseView, 'buildEntrySpec, [s]);
  244.                endpoint:SetInputSpec(endpoint.waitForEntries);
  245.             end,
  246.             discardAfter: 1000,
  247.          },
  248.       
  249.          waitForEntries:
  250.          {
  251.             InputForm: 'string,
  252.             endCharacter: UnicodeCR,
  253.             InputScript: func(endpoint, s)
  254.             begin
  255.                if BeginsWith(s, "BYE!") then
  256.                begin
  257.                   Perform(endpoint.slurpBaseView, 'epDisconnect, []);
  258.                   SetValue(endpoint.slurpBaseView.receiveBtn, 'text, "Receive...");
  259.                   Perform(endpoint.slurpBaseView, 'newStatus, ["Slurp complete - Tap Receive... to Slurp another..."]);
  260.                end;
  261.                else
  262.                begin
  263.                   Perform(endpoint.slurpBaseView, 'addNewEntry, [s]);
  264.                   endpoint:SetInputSpec(endpoint.waitForEntries);
  265.                end;
  266.             end,
  267.             discardAfter: 1000,
  268.          }
  269.       },
  270.     nextInputString:
  271.       func()
  272.       begin
  273.          local sPos, s;
  274.       
  275.          sPos := StrPos(entryString, "\t", entryIndex);
  276.          if not sPos then
  277.             sPos := StrPos(entryString, "\n", entryIndex);
  278.       
  279.          s := SubStr(entryString, entryIndex, sPos - entryIndex);
  280.          entryIndex := sPos + 1;
  281.          s;
  282.       end,
  283.     entryString: "Text",
  284.     title: "Slurp",
  285.     commEndPt: nil,
  286.     entrySpecFunc:
  287.       func()
  288.       begin
  289.       end,
  290.     buildEntrySpec:
  291.       /* BuildEntrySpec
  292.           Compile a WallyScript frame definition and get the resulting object.
  293.       
  294.           Slots used:
  295.               entrySpec, entrySpecFunc
  296.               
  297.           Methods used:
  298.               n/a
  299.           
  300.           Assumptions:
  301.               
  302.       */
  303.       func(s)
  304.       begin
  305.          :newStatus("BuildEntrySpec: before Compile");
  306.          entrySpecFunc := Compile(s);
  307.          :newStatus("BuildEntrySpec: before entrySpecFunc()");
  308.          entrySpec := :entrySpecFunc();
  309.          :newStatus("BuildEntrySpec: after entrySpecFunc()");
  310.       end,
  311.     epConnect:
  312.       func()
  313.       begin
  314.          local   epErr := nil;
  315.       
  316.          :newStatus("Connecting...");
  317.          epErr := commEndPt:Connect(nil, nil);
  318.          Perform(epState, 'showState, ["After Connect:"]);
  319.          if epErr then
  320.             :newStatus("Error trying to connect:" && NumberStr(epErr));
  321.          else begin
  322.             :newStatus("Connecting...done.");
  323.             :newStatus("Setting input spec...");
  324.             commEndPt:SetInputSpec(commEndPt.waitForSoupName);
  325.             Perform(epState, 'showState, ["After SetInputSpec:"]);
  326.             :newStatus("Setting input spec...done.");
  327.             :newStatus("Waiting for soup name...");
  328.          end;
  329.       end,
  330.     epDeferredDisconnect:
  331.       func()
  332.       begin
  333.          commEndPt:Abort();
  334.       
  335.          commEndPt:Release();
  336.       
  337.       //   commEndPt:Dispose();
  338.       end,
  339.     newStatus:
  340.       func(msg)
  341.       begin
  342.          statusBox:newMsg(msg);
  343.          RefreshViews();
  344.       end,
  345.     slurpSound: theSlurpSound,
  346.     entryIndex: nil,
  347.     numEntries: nil,
  348.     debug: "slurpBaseView",
  349.     buildEntry:
  350.       /* BuildEntry
  351.           Convert a tab delimited string of data into a soup entry (ie. frame)
  352.       
  353.           Slots used:
  354.               n/a
  355.               
  356.           Methods used:
  357.               matchTypes, nextInputString
  358.           
  359.           Assumptions:
  360.               currentFrameOrArray parameter is initialized to a frame.
  361.       */
  362.       func(currentFrameOrArray)
  363.       begin
  364.           // For each slot in the frame or each element in the array.
  365.           // The cool thing about foreach is that it doesn't care.  By
  366.           // using the path foreach creates, we can even assign values
  367.           // with the exact same code...
  368.           foreach path, value in currentFrameOrArray do begin
  369.               // Get the real class of the first slot/element.  In the
  370.               // case of the "Names" soup, the frame containing the
  371.               // person's name has a class slot set to 'person.  Because
  372.               // of this, the ClassOf function returns 'person instead
  373.               // of 'frame.  Using PrimClassOf (ie. Prim(itive)ClassOf)
  374.               // we can find out the real type.
  375.               local pClass := PrimClassOf(value);
  376.               
  377.               // Since frames/arrays can contain other frames/arrays,
  378.               // we can use recursion to simplify the function.  If
  379.               // we run across an element that is a frame/array, we
  380.               // just call ourself with the new path.  We Clone the
  381.               // spec value to reduce garbage collection and prevent
  382.               // having seperate code for creating frames and arrays.
  383.               if pClass = 'frame or pClass = 'array then begin
  384.                   currentFrameOrArray.(path) := Clone(value);
  385.                   :BuildEntry(currentFrameOrArray.(path));
  386.               end; else
  387.               
  388.               // Finally the real work.  If the slot value is not a
  389.               // frame/array, assign the new value.  getNextField
  390.               // returns the next tab-delimited string from the input
  391.               // buffer.  matchTypes is used to coerce the string
  392.               // into the type specified by value.
  393.               // NOTE 
  394.               //    We pass value instead of ClassOf(value) because
  395.               //    some types are specified using the contents of
  396.               //    a string.  See matchTypes for more info...
  397.                   currentFrameOrArray.(path) := :matchTypes(:nextInputString(), value);
  398.        end;
  399.        currentFrameOrArray;
  400.       end,
  401.     matchTypes:
  402.       /* matchTypes
  403.           Coerce the type of a value to match another.  
  404.       
  405.           Slots used:
  406.               n/a
  407.               
  408.           Methods used:
  409.               n/a
  410.           
  411.           Assumptions:
  412.          The type specified by valueType is never Frame or Array.
  413.          If the type is string, then the real type is specified
  414.          as a symbol stored within that string.  For example,
  415.             "string"   Coerce the value to type string
  416.             "date"     Coerce the value into a date value
  417.          If the string is specified as:
  418.             "stringWithClass"
  419.          then the valueString is made into a symbol, and the
  420.          type of the string becomes that symbol (ie. name, company). 
  421.        
  422.       */
  423.       func(valueString, valueType)
  424.       begin
  425.          local theType := ClassOf(valueType);
  426.       
  427.          // If valueType is string, get real type from string contents.
  428.          if theType = 'string then
  429.             theType := MakeSymbol(valueType);
  430.           
  431.       //   :newStatus("matchTypes:" && valueString && theType);
  432.       
  433.          if theType = 'string then
  434.             valueString;
  435.          else
  436.          if theType = 'int then
  437.             RintToL(StringToNumber(valueString));
  438.          else
  439.          if theType = 'real then
  440.             StringToNumber(valueString);
  441.          else
  442.          if theType = 'symbol then
  443.             MakeSymbol(valueString);
  444.          else
  445.          if theType = 'date then
  446.             StringToDate(valueString);
  447.          else
  448.          // Special, extra-strange stuff for handling the Names soup.
  449.          // Other soups may not require this code...
  450.          if theType = 'stringWithClass then
  451.             MakeSymbol(valueString);
  452.          else begin
  453.             if StrLen(valueString) > 0 then
  454.                SetClass(valueString, theType);
  455.          end;
  456.       end,
  457.     targetSoupName: nil,
  458.     UnRegisterCardSoup:
  459.       func(soupName)
  460.         begin
  461.           //first check for system provided function
  462.           if functions.UnRegisterCardSoup then
  463.             return UnRegisterCardSoup(soupName);
  464.       
  465.           local pos := ArrayPos(CardSoups,soupName,0,func(x,y) ClassOf(y)='String AND StrEqual(x,y));
  466.           if pos then ArrayRemoveCount(CardSoups,pos,2);
  467.         end
  468.    };
  469.  
  470. statusBoxLabel := /* child of slurpBaseView */
  471.    {text: "Slurp Status:",
  472.     viewBounds: {left: 79, top: 18, right: 149, bottom: 34},
  473.     viewFont: simpleFont9+tsBold,
  474.     viewJustify: 8388610,
  475.     _proto: protoStaticText,
  476.     debug: "statusBoxLabel"
  477.    };
  478.  
  479.  
  480.  
  481. receiveBtn := /* child of slurpBaseView */
  482.    {text: "Receive...",
  483.     buttonClickScript:
  484.       func()
  485.       begin
  486.          numEntries := 0;
  487.          if StrEqual(self.text, "Receive...") then
  488.          begin
  489.             Perform(self._parent, 'epInit, []);
  490.       
  491.             Perform(self._parent, 'epConnect, []);
  492.       
  493.             SetValue(self, 'text, "Disconnect");
  494.          end;
  495.          else
  496.          begin
  497.             Perform(self._parent, 'epDisconnect, []);
  498.             SetValue(self, 'text, "Receive...");
  499.          end;
  500.       //   PlaySound(slurpSound);
  501.       end,
  502.     viewBounds: {left: 52, top: 164, right: 184, bottom: 179},
  503.     _proto: protoTextButton,
  504.     debug: "receiveBtn"
  505.    };
  506. // View receiveBtn is declared to slurpBaseView
  507.  
  508.  
  509.  
  510.  
  511. // ---- File protoVT42 ----
  512. protoVT42 :=
  513.    {viewFlags: 67108923,
  514.     viewFormat: 337,
  515.     newmsg:
  516.       func(msg)
  517.       begin
  518.          if lastChat then
  519.             while Ticks() - lastChat < 10 do begin
  520.                // Nothing...
  521.             end;
  522.          else
  523.             lastChat := Ticks();
  524.       
  525.          SetValue(self.term, 'text, msg);
  526.          SetValue(self.term, 'viewBounds, viewBounds);
  527.       
  528.          RefreshViews();
  529.       end,
  530.     lastChat: nil,
  531.     viewclass: 77,
  532.     debug: "protoVT42"
  533.    };
  534.  
  535. term := /* child of protoVT42 */
  536.    {viewFlags: 67108923,
  537.     viewFormat: 257,
  538.     viewlinespacing: 13,
  539.     viewFont: simpleFont9,
  540.     viewSetupFormScript:
  541.       func()
  542.       begin
  543.          inherited:?viewSetupFormScript();
  544.          self.viewBounds := Clone(viewBounds);
  545.          viewBounds.right := viewBounds.right - viewBounds.left - 2;
  546.          viewBounds.left := 2;
  547.          viewBounds.bottom := viewBounds.bottom - viewBounds.top - 2;
  548.          viewBounds.top := 2;
  549.       end,
  550.     viewclass: 81,
  551.     debug: "term"
  552.    };
  553. // View term is declared to protoVT42
  554.  
  555.  
  556.  
  557.  
  558. // ---- Back in File SlurpBaseView.t ----
  559. statusBox := /* child of slurpBaseView */
  560.    {viewBounds: {left: 12, top: 33, right: 225, bottom: 62},
  561.     _proto: protoVT42,
  562.     debug: "statusBox"
  563.    };
  564. // View statusBox is declared to slurpBaseView
  565.  
  566.  
  567.  
  568. epStateLabel := /* child of slurpBaseView */
  569.    {text: "Connection State:",
  570.     viewBounds: {left: 63, top: 185, right: 170, bottom: 199},
  571.     viewClickScript:
  572.       func(unit)
  573.       begin
  574.          epState:showState("Current state:");
  575.       end,
  576.     viewFlags: 515,
  577.     viewFont: simpleFont9+tsBold,
  578.     viewJustify: 8388610,
  579.     _proto: protoStaticText,
  580.     debug: "epStateLabel"
  581.    };
  582. // View epStateLabel is declared to slurpBaseView
  583.  
  584.  
  585.  
  586. epState := /* child of slurpBaseView */
  587.    {viewBounds: {left: 15, top: 199, right: 216, bottom: 216},
  588.     lastShowTime: nil,
  589.     showState:
  590.       func(msg)
  591.       begin
  592.          local theState := commEndPt:State();
  593.       
  594.          if theState then begin
  595.             if lastShowTime then
  596.                while Ticks() - lastShowTime < 10 do begin
  597.                   // Nothing...
  598.                end;
  599.       
  600.             :newMsg(msg && stateLabels[theState]);
  601.             RefreshViews();
  602.       
  603.             lastShowTime := Ticks();
  604.          end;
  605.       end,
  606.     stateLabels:
  607.       [ "Uninitialized",
  608.                               "Unbound",
  609.                               "Idle",
  610.                               "Out Conn Pending",
  611.                               "In Conn Pending",
  612.                               "Data Transfer",
  613.                               "Out Release Pending",
  614.                               "In Release Pending",
  615.                               "In Flux"],
  616.     _proto: protoVT42,
  617.     debug: "epState"
  618.    };
  619. // View epState is declared to slurpBaseView
  620.  
  621.  
  622.  
  623. _view000 := /* child of slurpBaseView */
  624.    {text: "Soup:",
  625.     viewBounds: {left: 11, top: 66, right: 43, bottom: 81},
  626.     _proto: protoStaticText
  627.    };
  628.  
  629.  
  630.  
  631. soupNameDisplay := /* child of slurpBaseView */
  632.    {text: "",
  633.     viewBounds: {left: 42, top: 67, right: 99, bottom: 81},
  634.     viewFont: simpleFont9,
  635.     viewFormat: 337,
  636.     _proto: protoStaticText,
  637.     debug: "soupNameDisplay"
  638.    };
  639. // View soupNameDisplay is declared to slurpBaseView
  640.  
  641.  
  642.  
  643. _view001 := /* child of slurpBaseView */
  644.    {text: "Entries Slurped:",
  645.     viewBounds: {left: 99, top: 66, right: 189, bottom: 82},
  646.     viewJustify: 8388610,
  647.     _proto: protoStaticText
  648.    };
  649.  
  650.  
  651.  
  652. entriesSlurped := /* child of slurpBaseView */
  653.    {text: "0",
  654.     viewBounds: {left: 187, top: 67, right: 226, bottom: 81},
  655.     viewFont: simpleFont9,
  656.     viewFormat: 337,
  657.     viewJustify: 8388610,
  658.     _proto: protoStaticText,
  659.     debug: "entriesSlurped"
  660.    };
  661. // View entriesSlurped is declared to slurpBaseView
  662.  
  663.  
  664.  
  665. _view002 := /* child of slurpBaseView */
  666.    {text: "Current Entry:",
  667.     viewBounds: {left: 76, top: 82, right: 157, bottom: 97},
  668.     _proto: protoStaticText
  669.    };
  670.  
  671.  
  672.  
  673. currentEntryDisplay := /* child of slurpBaseView */
  674.    {viewBounds: {left: 12, top: 97, right: 222, bottom: 155},
  675.     _proto: protoVT42,
  676.     debug: "currentEntryDisplay"
  677.    };
  678. // View currentEntryDisplay is declared to slurpBaseView
  679.  
  680.  
  681.  
  682.  
  683.  
  684.  
  685.  
  686. // ---- Beginning of section for non used Layout files ----
  687.  
  688. // End of output